﻿using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
using ZFramework.Runtime;

namespace ZFramework.Editor
{
    //收集ui package信息
    public class FGuiPackageCollector : AssetPostprocessor
    {
        private class PackageInfo
        {
            public string PkgName;
            public string DescAssetPath;
            public string AtlasRootPath;
        }

        private const string OutputFilePath = "Assets/Res/UI/PackageInfoAsset/FguiPackageInfoAsset.asset";

        private const string FGuiStaticDescAssetRootPath = "Assets/Res/UI/FGUI/";     //存放静态的_fui.bytes
        private const string FGuiDynamicDescAssetRootPath = "Assets/Res/UI/FGUI/";     //存放静态的_fui.bytes

        private const string FGuiStaticAtlasRootPath = "Assets/Res/UI/FguiAtlas";
        private const string FGuiDynamicAtlasRootPath = "Assets/Res/UI/FguiAtlas";

        private static Dictionary<string, PackageInfo> _pkgName2PackageInfos = new Dictionary<string, PackageInfo>();
        
        
        //收集所有的.fgui.bytes文件
        private static void CollectDescAsset(string descAssetRootPath, string atlasRootPath)
        {
            var files = Directory.GetFiles(descAssetRootPath, "*_fui.bytes", SearchOption.AllDirectories);
            for (int i = 0; i < files.Length; i++)
            {
                string importName = files[i];
                string pkgName = GetPackageNameByFuiFilePath(importName);
                PackageInfo info = new PackageInfo();
                info.PkgName = pkgName;
                info.AtlasRootPath = atlasRootPath;
                info.DescAssetPath = importName;
                _pkgName2PackageInfos[pkgName] = info;
            }
        }
        
        private static string GetPackageNameByFuiFilePath(string path)
        {
            int charIndex = path.LastIndexOf("_", StringComparison.Ordinal);
            string prePartName = path.Substring(0, charIndex);

            int index = prePartName.LastIndexOf("/", StringComparison.Ordinal);
            string name = prePartName.Substring(index + 1);
            return name;
        }
        
        [MenuItem("Tools/RefreshFGUIPackageInfoAssets")]
        public static void RefreshPackageAssets()
        {
            _pkgName2PackageInfos.Clear();
            CollectDescAsset(FGuiStaticDescAssetRootPath, FGuiStaticAtlasRootPath);
            //CollectDescAsset(FGuiDynamicDescAssetRootPath, FGuiDynamicAtlasRootPath);
            GenerateFairyGuiPackageAsset();
        }

        private static void GenerateFairyGuiPackageAsset()
        {
            if (_pkgName2PackageInfos.Count <= 0)
            {
                return;
            }

            FguiAllPackageInfoAsset asset = null;
            if (!File.Exists(OutputFilePath))
            {
                asset = ScriptableObject.CreateInstance<FguiAllPackageInfoAsset>();
                asset.name = OutputFilePath;
                AssetDatabase.CreateAsset(asset, OutputFilePath);
            }
            else
            {
                asset = AssetDatabase.LoadAssetAtPath<FguiAllPackageInfoAsset>(OutputFilePath);
            }

            List<string> packageNames = new List<string>();
            List<string> descAssetPaths = new List<string>();
            List<string> atlasRootPaths = new List<string>();
            foreach (var item in _pkgName2PackageInfos)
            {
                var info = item.Value;
                packageNames.Add(info.PkgName);
                descAssetPaths.Add(info.DescAssetPath);
                atlasRootPaths.Add(info.AtlasRootPath);
            }
            asset.Set(packageNames.ToArray(), descAssetPaths.ToArray(), atlasRootPaths.ToArray());
            EditorUtility.SetDirty(asset);
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
        }
        
        private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
        {
            bool needRefreshPackageAsset = false;
            if (importedAssets.Length > 0)
            {
                if (CheckDir(importedAssets, FGuiStaticDescAssetRootPath))
                {
                    needRefreshPackageAsset = true;
                }
            }

            if (movedAssets.Length > 0)
            {
                if (CheckDir(movedAssets, FGuiStaticDescAssetRootPath))
                {
                    needRefreshPackageAsset = true;
                }
            }

            if (needRefreshPackageAsset)
            {
                RefreshPackageAssets();
            }
        }
        
        //检查是否是存放_fui.bytes文件
        private static bool CheckDir(string[] dirs, string targetPath)
        {
            for (int i = 0; i < dirs.Length; i++)
            {
                string str = dirs[i];
                if (str.StartsWith(targetPath))
                {
                    return true;
                }
            }
            return false;
        }
    }
}